package com.liuyu.common.framework.security.filter;

import com.alibaba.fastjson.JSON;
import com.liuyu.common.framework.common.constant.SelfPowerConstants;
import com.liuyu.common.framework.web.response.ApiResponse;
import jakarta.servlet.*;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.servlet.http.HttpSession;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.util.AntPathMatcher;
import org.springframework.util.PathMatcher;

import java.io.IOException;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;

/**
 //@WebFilter
 * @ClassName SecurityFilter
 * @Description: TODO
 * @Author: liuyu
 * @Date: Created in 2020/12/25 20:44
 * @Version: 1
 * @Modified By:
 */
@Slf4j
public class SecurityFilter implements Filter {
    public static final String PARAM_NAME_EXCLUSIONS = "exclusions";
    /**
     *不需要登录就可以访问的路径(比如:注册登录等)
     */
    private Set<String> excludesPattern;


    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        //这里是注册类中添加的白名单，转为Set集合
        String param = filterConfig.getInitParameter(PARAM_NAME_EXCLUSIONS);
        if (param != null && param.trim().length() != 0) {
            excludesPattern = new HashSet(Arrays.asList(param.split("\\s*,\\s*")));
        }

    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        HttpServletRequest request = (HttpServletRequest) servletRequest;
        HttpServletResponse response = (HttpServletResponse) servletResponse;
        HttpSession session = request.getSession(false);
        String uri = request.getServletPath();
        //下面这行代码是业务需求，获取请求参数 判断是否需要过滤，白名单中的路径不需要过滤，可以自由发挥
        boolean needFilter = isNeedFilter(uri);
        if (!needFilter) {
            //不需要过滤直接传给下一个过滤器
            filterChain.doFilter(servletRequest, servletResponse);
        } else {
            if (session == null) {
                log.info("登录失败,没有获取到sessionId");
                response.setCharacterEncoding("UTF-8");
                response.setContentType("application/json; charset=utf-8");
                response.getWriter().write(JSON.toJSONString(ApiResponse.customize("1012", "请重新登录")));
                return;
            }
            //这里获取用户的权限，这个可以参考我的springboot整合shiro的数据库表设计
            String openId = (String) session.getAttribute(SelfPowerConstants.SessionInfo.OPEN_ID);
            String userId = (String) session.getAttribute(SelfPowerConstants.SessionInfo.USER_CODE);
            if (StringUtils.isBlank(openId) && StringUtils.isBlank(userId)) {
                log.info("登录失败,sessionId:{}", session.getId());
                response.setCharacterEncoding("UTF-8");
                response.setContentType("application/json; charset=utf-8");
                response.getWriter().write(JSON.toJSONString(ApiResponse.customize("1012", "请重新登录")));
            } else {
                filterChain.doFilter(servletRequest, servletResponse);
            }
        }
    }

    /**
     * 是否需要过滤
     * @param uri
     * @return
     */
    public boolean isNeedFilter(String uri) {
        PathMatcher pathMatcher = new AntPathMatcher();
        for (String includeUrl : excludesPattern) {
            if (pathMatcher.match(includeUrl, uri)) {
                log.info("不需要验证:{}", uri);
                return false;
            }
        }
        return true;
    }


    @Override
    public void destroy() {

    }
}
